﻿using System.Net;
using System.Threading.Tasks;
using Deer.Extension;
using Letter.IO.Binary;
using Letter.IO.Transports;
using Letter.Net.Tcp;

namespace Telex;

sealed class TcpClient : ANetwork
{
    public TcpClient(SslClientConfig sslClientConfig, string secretkey, RpcHost host)
    {
        this.host = host;
        this.secretkey = secretkey;
        this.sslClientConfig = sslClientConfig;
    }
    
    private ITcpClient client;
    private RpcHost host;
    private string secretkey;
    private SslClientConfig sslClientConfig;

    public ValueTask<RpcHost> ConnectAsync(IPEndPoint point)
    {
        var tcs = new TaskCompletionSource<RpcHost>();
        this.client = TcpProvider.Client();
        this.client.ConfigureConnection(() =>
        {
            return this.OnConfigureConnection(tcs);
        });
        this.client.Build();
        this.client.ConnectAsync(point).Ignore();
        return new ValueTask<RpcHost>(tcs.Task);
    }

    protected override AConnection OnConfigureConnection(object token)
    {
        var tcs = (TaskCompletionSource<RpcHost>) token;
        var config = new ConnectionFixedConfig()
        {
            host = this.host,
            order = BinaryOrder.BigEndian,
            secretkey = this.secretkey,
            onConnect = this.OnConnect,
            onDisconnect = this.OnDisconnect
        };
        
        RpcClientConnection connection;
        if (sslClientConfig == null)
        {
            connection = new RpcClientConnection(ref config, tcs);
        }
        else
        {
            connection = new RpcClientConnection(
                ref config,
                sslClientConfig.sslClientOptions,
                sslClientConfig.sslClientStreamFactory,
                tcs);
        }
        
        return connection;
    }

    public override ValueTask StopAsync()
    {
        return new ValueTask(client.StopAsync());
    }
}
